<template>
    <el-dialog class="add-spec-dialog" v-model="show" width="800px" destroy-on-close @closed="closedHandle">
        <template #header>
            <span>{{ title }}</span>
        </template>
        <template #default>
            <el-form ref="formRef" :rules="rules" :model="form" label-width="auto" @submit.prevent>
                <el-form-item class="custom-form-item" label="规格名称" prop="attributeName">
                    <el-input
                        maxlength="10"
                        v-model.trim="form.attributeName"
                        show-word-limit
                        class="custom-spec-input mb0"
                        placeholder="请输入规格名称"></el-input>
                </el-form-item>
                <el-form-item label="规格值" prop="attr">
                    <div class="custom-spec-content">
                        <template v-for="(item, index) in form.attr" :key="item.id">
                            <el-tag
                                v-if="tagInputIndex !== index"
                                class="custom-spec-tag"
                                closable
                                size="large"
                                hit
                                effect="plain"
                                :disable-transitions="false"
                                @click="showTagInput(item.id, index, item.attrName)"
                                @close="handleClose(index)">
                                {{ item.attrName }}
                            </el-tag>
                            <el-input
                                v-if="tagInputIndex === index"
                                maxlength="50"
                                ref="tagInputRef"
                                v-model.trim="item.attrName"
                                class="custom-spec-input"
                                show-word-limit
                                @keyup.enter="handleTagInputConfirm(item.attrName, index)"
                                @blur="handleTagInputConfirm(item.attrName, index)" />
                        </template>

                        <el-input
                            v-if="inputVisible"
                            maxlength="50"
                            ref="inputRef"
                            v-model.trim="inputValue"
                            class="custom-spec-input"
                            show-word-limit
                            @keyup.enter="handleInputConfirm"
                            @blur="handleInputConfirm" />
                        <el-button
                            v-if="!inputVisible && form.attr.length < 100"
                            class="button-new-tag"
                            @click="showInput">
                            + 添加规格值
                        </el-button>
                    </div>
                </el-form-item>
            </el-form>
        </template>
        <template #footer>
            <div style="flex: auto">
                <el-button plain @click="closeHandler">取消</el-button>
                <el-button type="primary" @click="submitHandler">确认</el-button>
            </div>
        </template>
    </el-dialog>
</template>

<script setup>
import { ref, computed, reactive, inject, nextTick } from 'vue';
import request from '@/request';
import { cloneDeep } from '@/commons/utils';
import { isNotEmpty } from '../../../../commons/utils';
import { ElMessage } from 'element-plus';

/** 通信bus */
const bus = inject('bus');

/** 弹框显示隐藏 */
const props = defineProps({
    modelValue: Boolean
});
const emit = defineEmits(['update:modelValue']);
const show = computed({
    get() {
        return props.modelValue;
    },
    set(val) {
        emit('update:modelValue', val);
    }
});

/** form表单 */
const fzForm = {
    id: '',
    attributeName: '',
    attr: []
};
const formRef = ref(null);
const form = reactive(cloneDeep(fzForm));
const row = reactive({});
let initAttr = reactive([]);
bus.on('spec:edit', row => {
    initAttr.length = 0;
    if (row.hasOwnProperty('id')) {
        Object.assign(initAttr, cloneDeep(row.attr));
        Object.assign(form, cloneDeep(row));
    } else {
        Object.assign(form, cloneDeep(fzForm));
        Object.assign(initAttr, []);
    }
});
const title = computed(() => {
    return isNotEmpty(form.id) ? '编辑规格' : '新增规格';
});

// 添加规格
const inputValue = ref('');
const inputVisible = ref(false);
const inputRef = ref();

const handleClose = index => {
    form.attr.splice(index, 1);
};

const showInput = () => {
    inputVisible.value = true;
    nextTick(() => {
        inputRef?.value?.input?.focus();
    });
};

const handleInputConfirm = () => {
    if (inputValue.value) {
        if (form.attr.find(item => inputValue.value === item.attrName)) {
            ElMessage({
                type: 'error',
                message: '已存在相同的规格名，请修改'
            });
            return;
        }
        form.attr.push({
            attrName: inputValue.value
        });
    }
    inputVisible.value = false;
    inputValue.value = '';
};

let tagInputIndex = ref(null);
const tagInputRef = ref();
let currentTagVal = ref(null);

const showTagInput = (id, index, attrName) => {
    tagInputIndex.value = index;
    currentTagVal.value = attrName;
    nextTick(() => {
        tagInputRef?.value?.[0]?.input?.focus();
    });
};

const handleTagInputConfirm = (attrName, index) => {
    if (attrName) {
        if (form.attr.find((item, i) => i !== index && attrName === item.attrName)) {
            ElMessage({
                type: 'error',
                message: '已存在相同的规格名，请修改'
            });
            return;
        }
        // form.attr[index].attrName = attrName;
        tagInputIndex.value = null;
        if (!form.attr.find(item => item.attrName === inputValue.value) && inputValue.value) {
            form.attr.push({ attrName: inputValue.value });
            inputVisible.value = false;
            inputValue.value = '';
        }
    }
};
/**
 * 是否重复
 */
const isRepetition = () => {
    const arr = form.attr.map(item => item.attrName);
    const newArr = Array.from(new Set(arr));
    return newArr.length != arr.length;
};

/**
 * 表单验证
 */
const checkAttr = ({ fullField, message }, value, callback) => {
    if (!isNotEmpty(value)) {
        callback(new Error('请添加规格值'));
    } else if (!form.attr.every(item => !!item.attrName)) {
        callback(new Error('规格值不能为空'));
    } else if (isRepetition()) {
        callback(new Error('含有重复的规格值'));
    } else {
        callback();
    }
};
const rules = reactive({
    attributeName: [{ required: true, message: '请输入规格名称', trigger: 'blur' }],
    attr: [{ validator: checkAttr, trigger: 'blur' }]
});

/**
 * 关闭drawer
 */
const closeHandler = () => {
    show.value = false;
};
/**
 * 弹窗关闭动画结束回调
 */
const closedHandle = () => {
    inputValue.value = '';
    tagInputIndex.value = null;
};
const submitHandler = () => {
    formRef.value.validate(async valid => {
        if (valid) {
            if (form.attr.find(item => item.attrName === inputValue.value)) {
                ElMessage.error('已存在相同的规格名，请修改');
                return;
            }
            const apiName = `spec${isNotEmpty(form.id) ? 'Update' : 'Creat'}`;
            if (isNotEmpty(form.id)) {
                const initIds = initAttr.map(item => item.id);
                const attrIds = form.attr.map(item => item.id);
                form.delAttrId = initIds.filter(id => !attrIds.find(aId => aId === id));
            }
            const { id, attributeName, attr, delAttrId } = form;
            await request(
                apiName,
                isNotEmpty(form.id)
                    ? {
                          id,
                          attributeName,
                          attr: attr.map(({ attrName, id }) => {
                              return {
                                  attrName,
                                  id
                              };
                          }),
                          delAttrId
                      }
                    : {
                          attributeName,
                          attr
                      }
            );
            ElMessage.success('操作成功');
            closeHandler();
            bus.emit('spec:query');
        }
    });
};
</script>
<style lang="scss" scoped>
.add-spec-dialog {
    .custom-spec-tag,
    .custom-spec-input,
    .button-new-tag {
        margin-right: 16px;
        margin-bottom: 16px;
    }
    .custom-spec-input {
        width: 400px;
    }
    .custom-spec-content {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        max-height: 350px;
        overflow-y: auto;
    }
    .custom-form-item {
        margin-bottom: 24px;
        :deep(.el-form-item__content) {
            .el-form-item__error {
                margin-top: 3px;
            }
        }
    }
    .mb0 {
        margin-bottom: 0;
    }
}
</style>
